#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QPixmap>
#include <QDebug>
#include <QBuffer>
#include <QCameraImageCapture>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow),
      manager(new QNetworkAccessManager(this))
{
    ui->setupUi(this);
    this->setWindowTitle("桥洞科技考勤");
    this->setWindowIcon(QIcon(":/img/aaa"));

    initCameraList();

    connect(manager, &QNetworkAccessManager::finished,
            this, &MainWindow::onUploadFinished);

    openCamera();

    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &MainWindow::updateCurrentTime);
    timer->start(1000); // 1000毫秒 = 1秒触发一次
    updateCurrentTime();
    getAttendRule();
}

MainWindow::~MainWindow()
{
    releaseCameraResources();
    delete manager;
    delete ui;
}

// 初始化摄像头设备列表（添加到下拉框）
void MainWindow::initCameraList()
{
    ui->comboBox->clear(); // 清空下拉框
    // 获取所有可用摄像头设备
    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    if (cameras.isEmpty())
    {
        ui->comboBox->addItem("无可用摄像头");
        return;
    }
    // 添加摄像头名称到下拉框
    for (const QCameraInfo &cameraInfo : cameras)
    {
        ui->comboBox->addItem(cameraInfo.description(), cameraInfo.deviceName());
    }
}

// 释放摄像头和预览窗口资源
void MainWindow::releaseCameraResources()
{
    // 停止并释放摄像头
    if (camera)
    {
        camera->stop();
        delete camera;
        camera = nullptr;
    }
    // 释放预览窗口
    if (videoWidget)
    {
        delete videoWidget;
        videoWidget = nullptr;
    }
    if (imageCapture)
    {
        delete imageCapture;
        imageCapture = nullptr;
    }
}

// 启动摄像头按钮点击事件
void MainWindow::openCamera()
{
    // 如果摄像头已启动，先释放资源
    if (camera && camera->state() == QCamera::ActiveState)
    {
        releaseCameraResources();
        return;
    }

    // 获取选中的摄像头设备名称（从下拉框的用户数据中获取，避免中文乱码）
    QString deviceName = ui->comboBox->currentData().toString();
    if (deviceName.isEmpty())
    {
        qWarning() << "未选择有效摄像头";
        return;
    }

    // 释放旧资源
    releaseCameraResources();

    // 创建摄像头对象
    camera = new QCamera(deviceName.toUtf8(), this);
    if (!camera->isAvailable())
    {
        qWarning() << "摄像头不可用：" << deviceName;
        delete camera;
        camera = nullptr;
        return;
    }

    imageCapture = new QCameraImageCapture(camera, this);
    QImageEncoderSettings settings = imageCapture->encodingSettings();
    settings.setCodec("image/jpg");
    settings.setQuality(QMultimedia::HighQuality);
    imageCapture->setEncodingSettings(settings);

    // 拍照回调
    connect(imageCapture, &QCameraImageCapture::imageCaptured,
            this, &MainWindow::onImageCaptured,
            Qt::UniqueConnection);

    // 创建预览窗口
    videoWidget = new QVideoWidget(ui->widget);
    videoWidget->resize(ui->widget->width(), ui->widget->height());
    videoWidget->setStyleSheet("background-color: black;"); // 背景黑色，提升预览效果
    videoWidget->show();

    // 绑定摄像头和预览窗口
    camera->setViewfinder(videoWidget);

    // 启动摄像头
    camera->start();
    qDebug() << "摄像头启动成功：" << deviceName;
}

// 下拉框选择改变事件（切换摄像头）
void MainWindow::on_comboBox_currentIndexChanged(int index)
{
    Q_UNUSED(index);
    releaseCameraResources();                // 无论摄像头是否活跃，都先释放资源
}


// 拍照完成回调：获取内存中的 QImage，直接上传
void MainWindow::onImageCaptured(int id, const QImage &image)
{
    Q_UNUSED(id);
    // 校验图片是否有效
    if (image.isNull())
    {
        QMessageBox::critical(this, "拍照失败", "未能获取有效照片！");
        isUploading = false;
        return;
    }

    // 将 QImage 转换为二进制流（JPG 格式，无需本地文件）
    QByteArray photoData;
    QBuffer buffer(&photoData);
    buffer.open(QIODevice::WriteOnly);
    // 压缩图片并写入缓冲区（格式：JPG，质量 80）
    if (!image.save(&buffer, "JPG", 80))
    {
        QMessageBox::critical(this, "转换失败", "图片转换为二进制流失败！");
        isUploading = false;
        return;
    }
    buffer.close(); // 无需手动关闭，QBuffer 会自动管理

    //  构建 HTTP 请求（multipart/form-data）
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

    // 添加图片二进制字段
    QHttpPart photoPart;
    QString fileName = QString("%1.jpg").arg(currentEmployeeId); // 虚拟文件名（后端可识别）
    photoPart.setHeader(QNetworkRequest::ContentDispositionHeader,
                        QVariant(QString("form-data; name=\"attendPhoto\"; filename=\"%1\"").arg(fileName)));
    photoPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); // 明确 MIME 类型
    photoPart.setBody(photoData);                                                    // 直接绑定内存中的二进制数据

    // 组装请求体并发送
    //    multiPart->append(useridPart);
    multiPart->append(photoPart);

    QUrl url("http://8.138.248.21:8080/api/attend/add");
    QNetworkRequest request(url);
    QNetworkReply *reply = manager->post(request, multiPart);
    multiPart->setParent(reply); // 让 reply 自动释放 multiPart，避免内存泄漏

    ui->statusbar->showMessage("照片已获取，正在上传签到信息...");
}

// 上传结果回调：解析服务器响应
void MainWindow::onUploadFinished(QNetworkReply *reply)
{
    // 无论成功/失败，都先重置上传状态，恢复按钮可用
    isUploading = false;
    updateCheckInButtonState(); // 启用按钮，恢复“打卡”文本

    // 原有响应解析逻辑（不变）
    if (reply->error() == QNetworkReply::NoError)
    {
        QByteArray response = reply->readAll();
        QJsonObject json = QJsonDocument::fromJson(response).object();
        if (json["success"].toBool(false))
        {
            QMessageBox::information(this, "签到成功", json["message"].toString("签到成功！"));
            currentEmployeeId.clear();
        }
        else
        {
            QString errorMsg = json["error"].toString("签到失败，请重试！");
            QMessageBox::critical(this, "签到失败", errorMsg);
        }
    }
    else
    {
        QMessageBox::critical(this, "上传失败",
                              QString("网络请求失败：%1").arg(reply->errorString()));
    }
    reply->deleteLater();

    ui->statusbar->showMessage("");
}

void MainWindow::getAttendRule() {
    QMap<QString, QString> params;
    params["rule_name"] = "标准工时制";

    HttpManager::instance()->get(
                QString(SERVER_BASE_URL) + "/api/attendance_rules/by_name",
                params,
                [this](const QJsonObject& result) {
        // 先检查请求是否成功
        if (!result["success"].toBool()) {
            QMessageBox::warning(this, "请求失败", result["message"].toString("获取考勤规则失败"));
            return;
        }

        // 检查数据是否存在
        QJsonArray dataArray = result["data"].toArray();
        if (dataArray.isEmpty()) {
            QMessageBox::warning(this, "无数据", "未查询到“标准工时制”的考勤规则");
            return;
        }

        // 提取时间数据并更新UI
        QJsonObject ruleData = dataArray[0].toObject();
        QTime workStartTime = QTime::fromString(ruleData["work_start"].toString(), "HH:mm:ss");
        QString workStartStr = workStartTime.isValid() ? workStartTime.toString("HH:mm") : "无效时间";

        // 处理下班时间（work_end）
        QTime workEndTime = QTime::fromString(ruleData["work_end"].toString(), "HH:mm:ss");
        QString workEndStr = workEndTime.isValid() ? workEndTime.toString("HH:mm") : "无效时间";

        // 更新UI
        ui->label_2->setText("签到时间 " + workStartStr);
        ui->label_3->setText("签退时间 " + workEndStr);
    },
    [this](int code, const QString& msg) {
        // 网络/请求错误处理
        QMessageBox::critical(this, "请求异常", QString("错误码: %1\n信息: %2").arg(code).arg(msg));
        ui->label_2->setText("签到时间 未获取到数据");
        ui->label_3->setText("签退时间 未获取到数据");
    }
    );
}

void MainWindow::updateCurrentTime()
{
    QString currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
    ui->label->setText(currentTime);
}

void MainWindow::on_pushButton_clicked()
{
    // 1. 检查是否正在上传（避免重复请求）
    if (isUploading) {
        QMessageBox::information(this, "提示", "正在处理当前打卡请求，请稍后再试！");
        return;
    }

    // 2. 原有摄像头检查逻辑
    if (!camera || camera->state() != QCamera::ActiveState)
    {
        QMessageBox::warning(this, "摄像头错误", "请先启动摄像头！");
        return;
    }
    if (!imageCapture)
    {
        QMessageBox::critical(this, "初始化错误", "拍照组件未就绪！");
        return;
    }

    // 3. 开始拍照上传，设置 isUploading 为 true，并禁用按钮
    isUploading = true;
    updateCheckInButtonState(); // 禁用按钮，显示“上传中...”

    // 4. 执行拍照（原有逻辑不变）
    if (!imageCapture->capture())
    {
        QMessageBox::critical(this, "拍照失败", "无法启动拍照操作！");
        // 拍照失败时，也要重置状态（否则按钮会一直禁用）
        isUploading = false;
        updateCheckInButtonState();
    }
    else
    {
        ui->statusbar->showMessage("正在拍照，请面对摄像头...");
    }
}

void MainWindow::updateCheckInButtonState() {
    ui->pushButton->setEnabled(!isUploading);
    if (isUploading) {
        ui->pushButton->setText("上传中..."); // 按钮文本提示
    } else {
        ui->pushButton->setText("打卡"); // 恢复默认文本
    }
}
